/**
 * 公共跳转方法
 * @author liux
 * @date 2023-08-15 14:17
 * @param { string } url 跳转路径
 * @param { "navigateTo" | "redirectTo" | "reLaunch" | "switchTab" } [mode=navigateTo] 跳转模式
 * @param { object } params 跳转传参
 * @example
 * goToPage({ url: 'pages/index/index', mode: 'navigateTo', params: {'id': 1} })
 * @returns { void }
 */
type pageMode = 'navigateTo' | 'redirectTo' | 'reLaunch' | 'switchTab'

interface goToPageInt {
    url: string
    mode?: pageMode
    params?: {
        [n: string]: string | number | boolean
    }
}

export const goToPage = ({ url, mode = 'navigateTo', params = {} }: goToPageInt): void => {
    if (!url || url.length === 0) {
        throw Error('"url" is a required parameter')
    }

    const urlEncode = (params: any = {}) => {
        const result :string[] = []
        for (const k in params) {
            if (!params[k]) continue
            result.push(k + '=' + params[k])
        }

        return result.join('&')
    }
    // const storage = JSON.parse(uni.getStorageSync('LX_user'))
    // const token = storage?.userInfo?.token
    // if(!token) {
    // 	url = 'pages/login/loginXcx'
    // 	mode = 'navigateTo'
    // }
    const queryStr = !isEmpty(params) ? '?' + urlEncode(params) : ''
    const obj = { url: `/${url}${queryStr}` }
    // console.log('obj', obj)
    switch (mode) {
        case 'navigateTo':
            uni.navigateTo(obj)
            break
        case 'redirectTo':
            uni.redirectTo(obj)
            break
        case 'reLaunch':
            uni.reLaunch(obj)
            break
        case 'switchTab':
            uni.switchTab(obj)
            break
        default:
            throw Error(`${mode} does not exist`)
    }
}

/**
 * 判断是否为空对象
 * @author liux
 * @date 2023-08-15 14:17
 * @license MIT
 * @param {*} object 源对象
 * @returns { boolean }
 */
export const isEmptyObject = (object: any): boolean => {
    return Object.keys(object).length === 0
}

/**
 * 判断是否为对象
 * @author liux
 * @date 2023-08-15 14:17
 * @license MIT
 * @param {*} object 源对象
 * @returns { boolean }
 */
export const isObject = (object: any): boolean => {
    return Object.prototype.toString.call(object) === '[object Object]'
}

/**
 * 判断是否为数组
 * @author liux
 * @license MIT
 * @param {*} object 源对象
 * @returns { boolean }
 */
export const isArray = (object: any): boolean => {
    return Object.prototype.toString.call(object) === '[object Array]'
}

/**
 * 判断是否为空
 * @author liux
 * @license MIT
 * @param {*} value 源对象
 * @returns { boolean }
 */
export const isEmpty = (value: any): boolean => {
    if (isArray(value)) {
        return value.length === 0
    }
    if (isObject(value)) {
        return isEmptyObject(value)
    }
    return !value
}

/**
 * 格式化时间戳（多格式）
 * @author liux
 * @license MIT
 * @param { number } time 长度为 10 | 13 的时间戳
 * @param { string } [format=yyyy-MM-dd] format 转换格式
 * @example
 * formatTime(1691744378556, 'yyyy-MM-dd HH:mm:ss')
 * @returns { string }
 */

export const formatTime = (time: number, format: string = 'yyyy-MM-dd HH:mm:ss'): string => {
    const len = time.toString().trim().length
    if (len !== 10 && len !== 13) {
        throw Error('"time" is a error parameter')
    }

    time = len !== 13 ? time * 1000 : time

    if (!time) return ''
    const date = new Date(time)
    const M = (date.getMonth() + 1).toString()
    const d = date.getDate().toString()
    const H = date.getHours().toString()
    const m = date.getMinutes().toString()
    const s = date.getSeconds().toString()
    const timeObject: {
        [n: string]: string
    } = {
        yyyy: date.getFullYear().toString(),
        MM: M.padStart(2, '0'),
        dd: d.padStart(2, '0'),
        HH: H.padStart(2, '0'),
        mm: m.padStart(2, '0'),
        ss: s.padStart(2, '0'),
        M: M,
        d: d,
        H: H,
        m: m,
        s: s
    }
    const reg = new RegExp(Object.keys(timeObject).join('|'), 'g')
    const res = format.replace(reg, (k) => {
        return timeObject[k]
    })
    return res
}

// 判断当前时间是否在一个时间区间内
export const isTimeIn = (start: string, end: string) => {
    // 获取当前时间
    const currentTime = new Date()
    const startArr = start.split(':').map(Number)
    // 设置开始时间为10:00
    const startTime = new Date()
    startTime.setHours(startArr[0], startArr[1])

    // 设置结束时间为20:00
    const endArr = end.split(':').map(Number)
    const endTime = new Date()
    endTime.setHours(endArr[0], endArr[1])

    // 检查当前时间是否在10:00到20:00之间
    if (currentTime >= startTime && currentTime <= endTime) {
        // console.log('当前时间在之间')
    } else {
        // console.log('当前时间不在之间')
    }
}

/**
 * 防抖函数
 * @author liux
 * @license MIT
 * @param {function} fn
 * @param {umber} [wait=1000] wait
 * @returns { void }
 */
export const debounce = <T extends (...args: any[]) => any>(fn: T, wait: number = 1000): ((...args: Parameters<T>) => void) => {
    let timer: any

    return function (this: any, ...args: Parameters<T>) {
        if (timer) clearTimeout(timer)

        timer = setTimeout(() => {
            fn.apply(this, args)
        }, wait)
    }
}

/**
 * 节流函数
 * @author liux
 * @date 2023-08-15 14:17
 * @license MIT
 * @param { function } fn
 * @param { number } [wait=1000] wait
 */
export const throttle = <T extends (...args: any[]) => any>(fn: T, wait: number = 1000) => {
    let timer: number = Date.now()
    return function (this: any, ...args: Parameters<T>) {
        if (Date.now() - timer >= wait) {
            fn.apply(this, args)
            timer = Date.now()
        }
    }
}

/**
 * 保存图片到本地
 * @author liux
 * @param { string } url 需要下载的图片
 * @example
 * saveImgData('/upload/images/img.png')
 * @returns
 */
export const saveImgData = debounce((url: string) => {
    uni.showLoading({ title: '图片保存中...', mask: true })
    // 判断图片地址是否有http
    if (url.indexOf('http') === -1) {
        url = import.meta.env.VITE_APP_BASE_URL + url
    }
    uni.downloadFile({
        url,
        success: (res: any) => {
            if (res.statusCode === 200) {
                uni.saveImageToPhotosAlbum({
                    filePath: res.tempFilePath,
                    success: () => {
                        uni.showToast({
                            title: '保存成功~',
                            icon: 'none',
                            duration: 2000
                        })
                    },
                    fail: () => {
                        uni.showToast({
                            title: '保存失败~',
                            icon: 'none',
                            duration: 2000
                        })
                    },
                    complete: () => {
                        uni.hideLoading()
                    }
                })
            }
        }
    })
})

/**
 * 设置剪贴板
 * @author liux
 * @param { string } data 需要复制的内容
 * @example
 * setClipboardData('123456')
 * @returns
 */
export const setClipboardData = (data: string) => {
    uni.setClipboardData({
        data: data,
        success: () => {
            uni.showToast({
                title: '复制成功',
                icon: 'none',
                duration: 2000
            })
        }
    })
}

export default {
    goToPage,
    formatTime,
    debounce,
    throttle,
    saveImgData,
    setClipboardData
}
